package com.microframework.netty.model;
import io.netty.channel.Channel;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 客户端会话 - 表示一个客户端连接的所有状态和信息
 */
public class ClientSession {
    private final Channel channel;          // 网络通道
    private final String clientId;          // 客户端唯一标识
    private final long createTime;          // 会话创建时间
    private volatile long lastActivityTime; // 最后活动时间
    private volatile boolean authenticated; // 是否已认证
    
    // 会话属性存储
    private final Map<String, Object> attributes = new ConcurrentHashMap<>();
    
    // 消息计数器
    private final AtomicInteger receivedMessages = new AtomicInteger(0);
    private final AtomicInteger sentMessages = new AtomicInteger(0);
    
    // 会话状态常量
    public static final int STATE_INIT = 0;
    public static final int STATE_CONNECTED = 1;
    public static final int STATE_AUTHENTICATED = 2;
    public static final int STATE_CLOSED = 3;
    private volatile int state = STATE_INIT;

    /**
     * 构造函数
     * @param channel 网络通道
     * @param clientId 客户端ID
     */
    public ClientSession(Channel channel, String clientId) {
        if (channel == null || clientId == null) {
            throw new IllegalArgumentException("Channel和clientId不能为null");
        }
        this.channel = channel;
        this.clientId = clientId;
        this.createTime = System.currentTimeMillis();
        this.lastActivityTime = this.createTime;
        this.state = STATE_CONNECTED;
    }

    // ========== 基础信息获取方法 ==========
    
    public Channel getChannel() {
        return channel;
    }

    public String getClientId() {
        return clientId;
    }

    public long getCreateTime() {
        return createTime;
    }

    public long getLastActivityTime() {
        return lastActivityTime;
    }

    public boolean isAuthenticated() {
        return authenticated;
    }

    public int getState() {
        return state;
    }

    // ========== 状态操作方法 ==========
    
    /**
     * 标记会话为已认证
     */
    public void markAuthenticated() {
        this.authenticated = true;
        this.state = STATE_AUTHENTICATED;
        updateActivityTime();
    }

    /**
     * 关闭会话
     */
    public void close() {
        this.state = STATE_CLOSED;
        if (channel != null && channel.isActive()) {
            channel.close();
        }
    }

    /**
     * 更新最后活动时间
     */
    public void updateActivityTime() {
        this.lastActivityTime = System.currentTimeMillis();
    }

    // ========== 消息计数方法 ==========
    
    public void incrementReceivedMessages() {
        receivedMessages.incrementAndGet();
        updateActivityTime();
    }

    public void incrementSentMessages() {
        sentMessages.incrementAndGet();
        updateActivityTime();
    }

    public int getReceivedMessageCount() {
        return receivedMessages.get();
    }

    public int getSentMessageCount() {
        return sentMessages.get();
    }

    // ========== 属性操作方法 ==========
    
    public void setAttribute(String key, Object value) {
        if (key != null) {
            attributes.put(key, value);
        }
    }

    @SuppressWarnings("unchecked")
    public <T> T getAttribute(String key) {
        return (T) attributes.get(key);
    }

    public void removeAttribute(String key) {
        attributes.remove(key);
    }

    public boolean hasAttribute(String key) {
        return attributes.containsKey(key);
    }

    // ========== 业务方法 ==========
    
    /**
     * 发送消息给客户端
     * @param message 要发送的消息
     * @return 发送是否成功
     */
    public boolean send(Object message) {
        if (channel != null && channel.isActive()) {
            channel.writeAndFlush(message);
            incrementSentMessages();
            return true;
        }
        return false;
    }

    /**
     * 检查会话是否活跃
     * @return 是否活跃
     */
    public boolean isActive() {
        return channel != null && channel.isActive() && state != STATE_CLOSED;
    }

    /**
     * 获取会话存活时间(毫秒)
     * @return 存活时间
     */
    public long getAliveTime() {
        return System.currentTimeMillis() - createTime;
    }

    @Override
    public String toString() {
        return "ClientSession{" +
                "clientId='" + clientId + '\'' +
                ", state=" + stateToString(state) +
                ", active=" + isActive() +
                ", createTime=" + createTime +
                ", lastActive=" + lastActivityTime +
                ", received=" + receivedMessages +
                ", sent=" + sentMessages +
                '}';
    }

    private String stateToString(int state) {
        switch (state) {
            case STATE_INIT: return "INIT";
            case STATE_CONNECTED: return "CONNECTED";
            case STATE_AUTHENTICATED: return "AUTHENTICATED";
            case STATE_CLOSED: return "CLOSED";
            default: return "UNKNOWN";
        }
    }
}